package com.example.houseitemmanagebackend.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.houseitemmanagebackend.dto.ItemDTO;
import com.example.houseitemmanagebackend.dto.ItemQueryDTO;
import com.example.houseitemmanagebackend.entity.*;
import com.example.houseitemmanagebackend.entity.Items;
import com.example.houseitemmanagebackend.exception.BusinessException;
import com.example.houseitemmanagebackend.mapper.CategoryMapper;
import com.example.houseitemmanagebackend.mapper.IconMapper;
import com.example.houseitemmanagebackend.mapper.ItemMapper;
import com.example.houseitemmanagebackend.mapper.LocationMapper;
import com.example.houseitemmanagebackend.mapper.StatusMapper;
import com.example.houseitemmanagebackend.service.ItemService;
import com.example.houseitemmanagebackend.vo.ItemVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.swing.*;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 物品服务实现类
 */
@Slf4j
@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ItemMapper itemMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private LocationMapper locationMapper;

    @Autowired
    private StatusMapper statusMapper;

    @Autowired
    private IconMapper iconMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 添加物品
     */
    @Override
    @Transactional
    @CacheEvict(value = "itemCache", allEntries = true)
    public void addItem(ItemDTO itemDTO) {
        // 验证消耗品必须设置数量
        if (itemDTO.getIsConsumable() != null && itemDTO.getIsConsumable() == 1) {
            if (itemDTO.getQuantity() == null || itemDTO.getQuantity() < 1) {
                throw new BusinessException(400, "消耗品必须设置数量且不能小于1");
            }
        } else {
            // 非消耗品，数量默认为1
            itemDTO.setQuantity(1);
            // 确保非消耗品的isConsumable为0
            if (itemDTO.getIsConsumable() == null) {
                itemDTO.setIsConsumable(0);
            }
        }

        Items items = new Items();
        BeanUtil.copyProperties(itemDTO, items);

        items.setCreatedAt(LocalDateTime.now());
        items.setUpdatedAt(LocalDateTime.now());

        // 检查状态是否有效
        if (items.getStatus() != null) {
            Status status = statusMapper.selectById(items.getStatus());
            if (status == null) {
                throw new BusinessException(400, "无效的状态值");
            }
        } else {
            // 设置默认状态为active
            items.setStatus("active");
        }
        // 插入数据
        itemMapper.insert(items);
    }

    /**
     * 更新物品
     */
    @Override
    @Transactional
    @CacheEvict(value = "itemCache", key = "'item:' + #userId + ':' + #itemDTO.id")
    public void updateItem(ItemDTO itemDTO, Integer userId) {
        if (itemDTO.getId() == null) {
            throw new BusinessException(400, "物品ID不能为空");
        }

        // 验证消耗品必须设置数量
        if (itemDTO.getIsConsumable() != null && itemDTO.getIsConsumable() == 1) {
            if (itemDTO.getQuantity() == null || itemDTO.getQuantity() < 1) {
                throw new BusinessException(400, "消耗品必须设置数量且不能小于1");
            }
        } else {
            // 非消耗品，数量默认为1
            itemDTO.setQuantity(1);
            // 确保非消耗品的isConsumable为0
            if (itemDTO.getIsConsumable() == null) {
                itemDTO.setIsConsumable(0);
            }
        }

        // 检查物品是否存在
        Items existItems = itemMapper.selectById(itemDTO.getId());
        if (existItems == null) {
            throw new BusinessException(404, "物品不存在");
        }

        Items items = new Items();
        BeanUtil.copyProperties(itemDTO, items);

        items.setUserId(userId);
        items.setUpdatedAt(LocalDateTime.now());

        // 检查状态是否有效
        if (items.getStatus() != null) {
            Status status = statusMapper.selectById(items.getStatus());
            if (status == null) {
                throw new BusinessException(400, "无效的状态值");
            }
        }

        // 检查分类是否有效
        if (items.getCategoryId() != null) {
            Category category = categoryMapper.selectById(items.getCategoryId());
            if (category == null || (category.getUserId() != null && !category.getUserId().equals(userId)
                    && category.getIsSystem() == 0)) {
                throw new BusinessException(400, "无效的分类ID");
            }
        }

        // 检查位置是否有效
        if (items.getLocationId() != null) {
            Locations locations = locationMapper.selectById(items.getLocationId());
            if (locations == null || (locations.getUserId() != null && !locations.getUserId().equals(userId)
                    && locations.getIsSystem() == 0)) {
                throw new BusinessException(400, "无效的位置ID");
            }
        }

        // 更新数据
        itemMapper.updateById(items);

        // 清除相关缓存
        String cacheKeyPattern = "itemList:*";
        clearCacheByPattern(cacheKeyPattern);
    }

    /**
     * 删除物品
     */
    @Override
    @Transactional
    @CacheEvict(value = "itemCache", key = "'item:' + #userId + ':' + #id")
    public void deleteItem(Integer id, Integer userId) {
        // 检查物品是否存在
        Items items = itemMapper.selectById(id);
        if (items == null) {
            throw new BusinessException(404, "物品不存在");
        }

        // 删除物品
        itemMapper.deleteById(id);

        // 清除相关缓存
        String cacheKeyPattern = "itemList:*";
        clearCacheByPattern(cacheKeyPattern);
    }

    /**
     * 根据ID查询物品
     */
    @Override
    @Cacheable(value = "itemCache", key = "'item:' + #userId + ':' + #id", unless = "#result == null")
    public ItemVO getItemById(Integer id, Integer userId) {
        // 从数据库查询
        Items items = itemMapper.selectById(id);
        if (items == null || !items.getUserId().equals(userId)) {
            throw new BusinessException(404, "物品不存在");
        }

        // 转换为VO对象
        return convertToItemVO(items);
    }

    /**
     * 分页查询物品列表
     */
    @Override
    public IPage<ItemVO> getItemPage(ItemQueryDTO queryDTO) {
        // 构建缓存键
        String cacheKey = "itemList:" + queryDTO.toString();

        // 尝试从缓存获取
        Object cachedResult = null;
        try {
            cachedResult = redisTemplate.opsForValue().get(cacheKey);
        } catch (Exception e) {
            log.error("从Redis获取物品分页数据失败: {}", e.getMessage());
            // 继续执行，回退到数据库查询
        }

        if (cachedResult != null) {
            return (IPage<ItemVO>) cachedResult;
        }

        // 构建分页对象
        Page<Items> page = new Page<>(queryDTO.getPage(), queryDTO.getSize());

        // 构建查询条件
        LambdaQueryWrapper<Items> queryWrapper = new LambdaQueryWrapper<>();

        // 根据分类ID过滤
        if (queryDTO.getCategoryId() != null) {
            queryWrapper.eq(Items::getCategoryId, queryDTO.getCategoryId());
        }

        // 根据位置ID过滤
        if (queryDTO.getLocationId() != null) {
            queryWrapper.eq(Items::getLocationId, queryDTO.getLocationId());
        }

        // 根据关键词过滤
        if (StrUtil.isNotBlank(queryDTO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper
                    .like(Items::getName, queryDTO.getKeyword())
                    .or()
                    .like(Items::getBrand, queryDTO.getKeyword())
                    .or()
                    .like(Items::getSpecification, queryDTO.getKeyword()));
        }

        // 根据消耗品类型过滤
        if (queryDTO.getIsConsumable() != null) {
            queryWrapper.eq(Items::getIsConsumable, queryDTO.getIsConsumable());
        }

        // 根据状态过滤
        if (StrUtil.isNotBlank(queryDTO.getStatus())) {
            queryWrapper.eq(Items::getStatus, queryDTO.getStatus());
        }

        // 排序处理
        if (StrUtil.isNotBlank(queryDTO.getSortField())) {
            // 这里使用switch-case处理不同的排序字段
            switch (queryDTO.getSortField()) {
                case "name":
                    if (queryDTO.getSortDesc() != null && queryDTO.getSortDesc()) {
                        queryWrapper.orderByDesc(Items::getName);
                    } else {
                        queryWrapper.orderByAsc(Items::getName);
                    }
                    break;
                case "price":
                    if (queryDTO.getSortDesc() != null && queryDTO.getSortDesc()) {
                        queryWrapper.orderByDesc(Items::getPrice);
                    } else {
                        queryWrapper.orderByAsc(Items::getPrice);
                    }
                    break;
                case "purchaseDate":
                    if (queryDTO.getSortDesc() != null && queryDTO.getSortDesc()) {
                        queryWrapper.orderByDesc(Items::getPurchaseDate);
                    } else {
                        queryWrapper.orderByAsc(Items::getPurchaseDate);
                    }
                    break;
                case "expiryDate":
                    if (queryDTO.getSortDesc() != null && queryDTO.getSortDesc()) {
                        queryWrapper.orderByDesc(Items::getExpiryDate);
                    } else {
                        queryWrapper.orderByAsc(Items::getExpiryDate);
                    }
                    break;
                default:
                    // 默认按照创建时间排序
                    queryWrapper.orderByDesc(Items::getCreatedAt);
            }
        } else {
            // 默认按照创建时间排序
            queryWrapper.orderByDesc(Items::getCreatedAt);
        }

        // 执行查询
        IPage<Items> itemsPage = itemMapper.selectPage(page, queryWrapper);

        // 转换为VO
        IPage<ItemVO> itemVOPage = itemsPage.convert(this::convertToItemVO);

        // 将结果存入缓存
        try {
            redisTemplate.opsForValue().set(cacheKey, itemVOPage, 10, TimeUnit.MINUTES);
        } catch (Exception e) {
            log.error("缓存物品分页数据失败: {}", e.getMessage());
            // 不抛出异常，继续正常返回结果
        }

        return itemVOPage;
    }

    @Override
    @Cacheable(value = "itemCache", key = "'itemList:'  + ':' + #locationId", unless = "#result == null")
    public List<ItemVO> getAllItems(Integer locationId, Integer userId) {
        LambdaQueryWrapper<Items> queryWrapper = new LambdaQueryWrapper<>();

        if (locationId != null) {
            queryWrapper.eq(Items::getLocationId, locationId);
        }

        List<Items> itemsList = itemMapper.selectList(queryWrapper);
        List<ItemVO> result = new ArrayList<>(itemsList.size());

        for (Items item : itemsList) {
            result.add(convertToItemVO(item));
        }

        return result;
    }

    /**
     * 根据缓存键模式清除缓存
     */
    private void clearCacheByPattern(String pattern) {
        Set<String> keys = redisTemplate.keys(pattern);
        if (keys != null && !keys.isEmpty()) {
            redisTemplate.delete(keys);
        }
    }

    /**
     * 转换为物品VO对象
     */
    private ItemVO convertToItemVO(Items items) {
        if (items == null) {
            return null;
        }

        ItemVO itemVO = new ItemVO();
        BeanUtil.copyProperties(items, itemVO);

        // 设置分类名称
        if (items.getCategoryId() != null) {
            Category category = categoryMapper.selectById(items.getCategoryId());
            if (category != null) {
                itemVO.setCategoryName(category.getName());
            }
        }

        // 设置位置名称
        if (items.getLocationId() != null) {
            Locations locations = locationMapper.selectById(items.getLocationId());
            if (locations != null) {
                itemVO.setLocationName(locations.getName());
            }
        }

        // 设置状态名称
        if (items.getStatus() != null) {
            Status status = statusMapper.selectById(items.getStatus());
            if (status != null) {
                itemVO.setStatus(status.getValue());
            }
        }

        // 设置图标ID
        if (items.getIconId() != null) {
            itemVO.setIconId(items.getIconId());
        }

        return itemVO;
    }

    /**
     * 导入物品数据
     */
    @Override
    @Transactional
    @CacheEvict(value = "itemCache", allEntries = true)
    public Map<String, Object> importItems(MultipartFile file, Integer locationId, Integer userId) {
        Map<String, Object> result = new HashMap<>();
        int totalRows = 0;
        int successCount = 0;
        int failCount = 0;
        List<String> errors = new ArrayList<>();

        try {
            // 检查文件类型
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null || originalFilename.isEmpty()) {
                throw new BusinessException(400, "文件名不能为空");
            }

            boolean isExcel = originalFilename.endsWith(".xlsx") || originalFilename.endsWith(".xls");
            boolean isCsv = originalFilename.endsWith(".csv");

            if (!isExcel && !isCsv) {
                throw new BusinessException(400, "只支持Excel(.xlsx, .xls)或CSV(.csv)文件格式");
            }

            // 读取文件
            List<Map<String, Object>> data;
            if (isExcel) {
                data = readExcelFile(file.getInputStream());
            } else {
                data = readCsvFile(file.getInputStream());
            }

            totalRows = data.size();

            // 验证位置ID
            if (locationId == null) {
                locationId = getDefaultLocationId(userId);
            } else {
                // 检查位置是否存在
                Locations location = locationMapper.selectById(locationId);
                if (location == null) {
                    throw new BusinessException(400, "指定的位置不存在");
                }
            }

            // 处理导入数据
            for (Map<String, Object> row : data) {
                try {
                    ItemDTO itemDTO = convertMapToItemDTO(row, locationId);
                    addItem(itemDTO);
                    successCount++;
                } catch (Exception e) {
                    failCount++;
                    errors.add(String.format("行 %d: %s", data.indexOf(row) + 2, e.getMessage()));
                    log.error("导入物品数据出错", e);
                }
            }

        } catch (Exception e) {
            log.error("导入物品数据出错", e);
            throw new BusinessException(500, "导入物品数据失败: " + e.getMessage());
        }

        result.put("totalRows", totalRows);
        result.put("successCount", successCount);
        result.put("failCount", failCount);
        result.put("errors", errors);

        return result;
    }

    /**
     * 导出物品数据
     */
    @Override
    public Resource exportItems(Integer locationId, String format, Boolean includeStock, Boolean includeExpired,
            Boolean includeCategories, Integer userId) {
        try {
            // 构建查询条件
            LambdaQueryWrapper<Items> queryWrapper = new LambdaQueryWrapper<>();

            // 添加用户条件
            queryWrapper.eq(Items::getUserId, userId);

            // 添加位置条件（如果指定了位置ID）
            if (locationId != null) {
                queryWrapper.eq(Items::getLocationId, locationId);
            }

            // 查询物品数据
            List<Items> items = itemMapper.selectList(queryWrapper);
            List<ItemVO> itemVOs = items.stream()
                    .map(this::convertToItemVO)
                    .collect(Collectors.toList());

            // 根据格式导出数据
            if ("excel".equalsIgnoreCase(format)) {
                return exportToExcel(itemVOs, includeStock, includeExpired, includeCategories);
            } else {
                return exportToCsv(itemVOs, includeStock, includeExpired, includeCategories);
            }
        } catch (Exception e) {
            log.error("导出物品数据出错", e);
            throw new BusinessException(500, "导出物品数据失败: " + e.getMessage());
        }
    }

    /**
     * 读取Excel文件
     */
    private List<Map<String, Object>> readExcelFile(InputStream inputStream) throws IOException {
        List<Map<String, Object>> data = new ArrayList<>();

        try (Workbook workbook = WorkbookFactory.create(inputStream)) {
            Sheet sheet = workbook.getSheetAt(0);

            // 获取表头行
            Row headerRow = sheet.getRow(0);
            if (headerRow == null) {
                throw new BusinessException(400, "Excel文件格式错误：缺少表头行");
            }

            // 解析表头
            List<String> headers = new ArrayList<>();
            for (int i = 0; i < headerRow.getLastCellNum(); i++) {
                Cell cell = headerRow.getCell(i);
                if (cell != null) {
                    headers.add(cell.getStringCellValue().trim());
                } else {
                    headers.add("");
                }
            }

            // 检查必要的列是否存在
            validateHeaders(headers);

            // 读取数据行
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null)
                    continue;

                Map<String, Object> rowData = new HashMap<>();
                boolean hasData = false;

                for (int j = 0; j < headers.size(); j++) {
                    if (j >= row.getLastCellNum())
                        continue;

                    Cell cell = row.getCell(j);
                    String header = headers.get(j);

                    if (header.isEmpty())
                        continue;

                    Object value = getCellValue(cell);
                    if (value != null) {
                        rowData.put(header, value);
                        hasData = true;
                    }
                }

                if (hasData) {
                    data.add(rowData);
                }
            }
        }

        return data;
    }

    /**
     * 读取CSV文件
     */
    private List<Map<String, Object>> readCsvFile(InputStream inputStream) throws IOException {
        List<Map<String, Object>> data = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
            // 读取表头
            String headerLine = reader.readLine();
            if (headerLine == null) {
                throw new BusinessException(400, "CSV文件格式错误：缺少表头行");
            }

            // 解析表头
            List<String> headers = Arrays.asList(headerLine.split(","));
            headers = headers.stream().map(String::trim).collect(Collectors.toList());

            // 检查必要的列是否存在
            validateHeaders(headers);

            // 读取数据行
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.trim().isEmpty())
                    continue;

                String[] values = line.split(",");
                Map<String, Object> rowData = new HashMap<>();
                boolean hasData = false;

                for (int i = 0; i < headers.size(); i++) {
                    if (i >= values.length)
                        continue;

                    String header = headers.get(i);
                    String value = values[i].trim();

                    if (!header.isEmpty() && !value.isEmpty()) {
                        rowData.put(header, value);
                        hasData = true;
                    }
                }

                if (hasData) {
                    data.add(rowData);
                }
            }
        }

        return data;
    }

    /**
     * 验证表头是否包含必要的列
     */
    private void validateHeaders(List<String> headers) {
        // 定义必要的列
        List<String> requiredHeaders = Arrays.asList("名称", "分类", "位置", "数量");

        // 检查必要的列是否存在
        List<String> missingHeaders = requiredHeaders.stream()
                .filter(header -> !headers.contains(header))
                .collect(Collectors.toList());

        if (!missingHeaders.isEmpty()) {
            throw new BusinessException(400, "文件格式错误：缺少必要的列 " + String.join(", ", missingHeaders));
        }
    }

    /**
     * 获取单元格的值
     */
    private Object getCellValue(Cell cell) {
        if (cell == null)
            return null;

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue();
                } else {
                    return cell.getNumericCellValue();
                }
            case BOOLEAN:
                return cell.getBooleanCellValue();
            case FORMULA:
                switch (cell.getCachedFormulaResultType()) {
                    case STRING:
                        return cell.getStringCellValue().trim();
                    case NUMERIC:
                        if (DateUtil.isCellDateFormatted(cell)) {
                            return cell.getDateCellValue();
                        } else {
                            return cell.getNumericCellValue();
                        }
                    default:
                        return null;
                }
            default:
                return null;
        }
    }

    /**
     * 将Map转换为ItemDTO对象
     */
    private ItemDTO convertMapToItemDTO(Map<String, Object> map, Integer locationId) {
        ItemDTO itemDTO = new ItemDTO();

        // 设置必要字段
        itemDTO.setName(getStringValue(map, "名称"));

        // 查找分类ID并设置
        String categoryName = getStringValue(map, "分类");
        if (categoryName != null) {
            // 通过分类名称查询分类ID
            LambdaQueryWrapper<Category> categoryQueryWrapper = new LambdaQueryWrapper<>();
            categoryQueryWrapper.eq(Category::getName, categoryName);
            Category category = categoryMapper.selectOne(categoryQueryWrapper);

            if (category != null) {
                itemDTO.setCategoryId(category.getId());
            } else {
                log.warn("导入时未找到名称为 '{}' 的分类", categoryName);
            }
        }

        // 如果未提供位置ID，则使用导入的位置名称查找位置
        if (locationId == null) {
            String locationName = getStringValue(map, "位置");
            if (locationName != null) {
                // 通过位置名称查询位置ID
                LambdaQueryWrapper<Locations> locationQueryWrapper = new LambdaQueryWrapper<>();
                locationQueryWrapper.eq(Locations::getName, locationName);
                Locations location = locationMapper.selectOne(locationQueryWrapper);

                if (location != null) {
                    itemDTO.setLocationId(location.getId());
                } else {
                    log.warn("导入时未找到名称为 '{}' 的位置", locationName);
                }
            }
        } else {
            itemDTO.setLocationId(locationId);
        }

        // 设置数量
        String quantityStr = getStringValue(map, "数量");
        if (quantityStr != null) {
            try {
                double doubleValue = Double.parseDouble(quantityStr);
                int quantity = (int) doubleValue;
                itemDTO.setQuantity(quantity);

                // 如果数量大于1，则设置为消耗品
                if (quantity > 1) {
                    itemDTO.setIsConsumable(1);
                } else {
                    itemDTO.setIsConsumable(0);
                }
            } catch (NumberFormatException e) {
                throw new BusinessException(400, "数量格式错误：" + quantityStr);
            }
        } else {
            // 默认数量为1，非消耗品
            itemDTO.setQuantity(1);
            itemDTO.setIsConsumable(0);
        }

        // 设置购买日期
        String purchaseDateStr = getStringValue(map, "购买日期");
        if (purchaseDateStr != null) {
            try {
                // 转换为LocalDate
                LocalDate purchaseDate = LocalDate.parse(purchaseDateStr);
                itemDTO.setPurchaseDate(purchaseDate);
            } catch (Exception e) {
                throw new BusinessException(400, "购买日期格式错误，请使用yyyy-MM-dd格式：" + purchaseDateStr);
            }
        } else {
            // 默认购买日期为当前日期
            itemDTO.setPurchaseDate(LocalDate.now());
        }

        // 设置价格
        String priceStr = getStringValue(map, "价格");
        if (priceStr != null) {
            try {
                // 转换为BigDecimal
                BigDecimal price = new BigDecimal(priceStr);
                itemDTO.setPrice(price);
            } catch (NumberFormatException e) {
                throw new BusinessException(400, "价格格式错误：" + priceStr);
            }
        }

        // 设置过期日期
        String expiryDateStr = getStringValue(map, "过期日期");
        if (expiryDateStr != null) {
            try {
                // 转换为LocalDate
                LocalDate expiryDate = LocalDate.parse(expiryDateStr);
                itemDTO.setExpiryDate(expiryDate);
            } catch (Exception e) {
                throw new BusinessException(400, "过期日期格式错误，请使用yyyy-MM-dd格式：" + expiryDateStr);
            }
        }

        // 设置备注
        String notes = getStringValue(map, "备注");
        if (notes != null) {
            itemDTO.setNotes(notes);
        }

        return itemDTO;
    }

    /**
     * 从Map中获取字符串值
     */
    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null)
            return null;

        return value.toString().trim();
    }

    /**
     * 获取默认位置ID
     */
    private Integer getDefaultLocationId(Integer userId) {
        // 查询用户的第一个位置
        LambdaQueryWrapper<Locations> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Locations::getUserId, userId);
        queryWrapper.orderByAsc(Locations::getId);
        queryWrapper.last("LIMIT 1");

        Locations location = locationMapper.selectOne(queryWrapper);
        if (location == null) {
            throw new BusinessException(400, "未找到默认位置，请先创建位置");
        }

        return location.getId();
    }

    /**
     * 导出数据到Excel
     */
    private Resource exportToExcel(List<ItemVO> items, Boolean includeStock, Boolean includeExpired,
            Boolean includeCategories) throws IOException {
        // 创建工作簿和工作表
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("物品列表");

            // 创建表头样式
            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);

            // 创建表头
            Row headerRow = sheet.createRow(0);
            List<String> headers = getExportHeaders(includeStock, includeExpired, includeCategories);

            for (int i = 0; i < headers.size(); i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers.get(i));
                cell.setCellStyle(headerStyle);
            }

            // 写入数据
            int rowNum = 1;
            for (ItemVO item : items) {
                Row row = sheet.createRow(rowNum++);
                int colNum = 0;

                // 基本信息
                row.createCell(colNum++).setCellValue(item.getName());
                row.createCell(colNum++).setCellValue(item.getLocationName());

                // 分类信息（如果需要）
                if (includeCategories) {
                    row.createCell(colNum++).setCellValue(item.getCategoryName());
                }

                // 库存信息（如果需要）
                if (includeStock) {
                    row.createCell(colNum++).setCellValue(item.getQuantity());
                    if (item.getIsConsumable() != null && item.getIsConsumable() == 1) {
                        row.createCell(colNum++).setCellValue("是");
                    } else {
                        row.createCell(colNum++).setCellValue("否");
                    }
                }

                // 购买信息
                Cell purchaseDateCell = row.createCell(colNum++);
                if (item.getPurchaseDate() != null) {
                    purchaseDateCell.setCellValue(item.getPurchaseDate().toString());
                }

                Cell priceCell = row.createCell(colNum++);
                if (item.getPrice() != null) {
                    priceCell.setCellValue(item.getPrice().doubleValue());
                }

                // 过期信息（如果需要）
                if (includeExpired) {
                    Cell expiryDateCell = row.createCell(colNum++);
                    if (item.getExpiryDate() != null) {
                        expiryDateCell.setCellValue(item.getExpiryDate().toString());
                    }
                }

                // 备注
                if (item.getNotes() != null) {
                    row.createCell(colNum).setCellValue(item.getNotes());
                }
            }

            // 调整列宽
            for (int i = 0; i < headers.size(); i++) {
                sheet.autoSizeColumn(i);
            }

            // 将工作簿写入临时文件
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);

            return new ByteArrayResource(outputStream.toByteArray());
        }
    }

    /**
     * 导出数据到CSV
     */
    private Resource exportToCsv(List<ItemVO> items, Boolean includeStock, Boolean includeExpired,
            Boolean includeCategories) throws IOException {
        // 获取表头
        List<String> headers = getExportHeaders(includeStock, includeExpired, includeCategories);

        // 创建CSV数据
        StringBuilder csv = new StringBuilder();

        // 添加表头
        csv.append(String.join(",", headers)).append("\n");

        // 添加数据行
        for (ItemVO item : items) {
            List<String> rowData = new ArrayList<>();

            // 基本信息
            rowData.add(csvEscape(item.getName()));
            rowData.add(csvEscape(item.getLocationName()));

            // 分类信息（如果需要）
            if (includeCategories) {
                rowData.add(csvEscape(item.getCategoryName()));
            }

            // 库存信息（如果需要）
            if (includeStock) {
                rowData.add(item.getQuantity() != null ? item.getQuantity().toString() : "");
                rowData.add(item.getIsConsumable() != null && item.getIsConsumable() == 1 ? "是" : "否");
            }

            // 购买信息
            rowData.add(item.getPurchaseDate() != null ? item.getPurchaseDate().toString() : "");
            rowData.add(item.getPrice() != null ? item.getPrice().toString() : "");

            // 过期信息（如果需要）
            if (includeExpired) {
                rowData.add(item.getExpiryDate() != null ? item.getExpiryDate().toString() : "");
            }

            // 备注
            rowData.add(csvEscape(item.getNotes()));

            csv.append(String.join(",", rowData)).append("\n");
        }

        // 返回CSV数据
        byte[] bytes = csv.toString().getBytes(StandardCharsets.UTF_8);
        return new ByteArrayResource(bytes);
    }

    /**
     * 获取导出表头
     */
    private List<String> getExportHeaders(Boolean includeStock, Boolean includeExpired, Boolean includeCategories) {
        List<String> headers = new ArrayList<>();

        // 基本信息
        headers.add("名称");
        headers.add("位置");

        // 分类信息（如果需要）
        if (includeCategories) {
            headers.add("分类");
        }

        // 库存信息（如果需要）
        if (includeStock) {
            headers.add("数量");
            headers.add("是否消耗品");
        }

        // 购买信息
        headers.add("购买日期");
        headers.add("价格");

        // 过期信息（如果需要）
        if (includeExpired) {
            headers.add("过期日期");
        }

        // 备注
        headers.add("备注");

        return headers;
    }

    /**
     * 转义CSV字段
     */
    private String csvEscape(String value) {
        if (value == null)
            return "";

        // 如果字段包含逗号、引号或换行符，则用引号包围并转义引号
        if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
            return "\"" + value.replace("\"", "\"\"") + "\"";
        }

        return value;
    }
}